package com.alibaba.csp.sentinel.dashboard.rule.nacos;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.convert.converter.Converter;

import java.util.List;
import java.util.Properties;

@EnableConfigurationProperties(NacosPropertiesConfiguration.class)
@Configuration
public class NacosConfiguration {

    @Bean
    public Converter<List<ApiDefinitionEntity>, String> apiDefEntityEncoder() {
        return new Converter<List<ApiDefinitionEntity>, String>() {
            @Override
            public String convert(List<ApiDefinitionEntity> source) {
                return JSON.toJSONString(source);
            }
        };
    }

    @Bean
    public Converter<String, List<ApiDefinitionEntity>> apiDefEntityDecoder() {
        return new Converter<String, List<ApiDefinitionEntity>>() {
            @Override
            public List<ApiDefinitionEntity> convert(String source) {
                return JSON.parseArray(source, ApiDefinitionEntity.class);
            }
        };
    }

    @Bean
    public Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() {
        //return JSON::toJSONString;
        return new Converter<List<FlowRuleEntity>, String>() {
            @Override
            public String convert(List<FlowRuleEntity> source) {
                return JSON.toJSONString(source);
            }
        };
    }


    @Bean
    public Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {
        return new Converter<String, List<FlowRuleEntity>>() {
            @Override
            public List<FlowRuleEntity> convert(String source) {
                return JSON.parseArray(source, FlowRuleEntity.class);
            }
        };
        //return s -> JSON.parseArray(s, FlowRuleEntity.class);
    }

    @Bean
    public Converter<List<GatewayFlowRuleEntity>, String> gatewayFlowRuleEntityEncoder() {
        return new Converter<List<GatewayFlowRuleEntity>, String>() {
            @Override
            public String convert(List<GatewayFlowRuleEntity> source) {
                return JSON.toJSONString(source);
            }
        };
    }


    @Bean
    public Converter<String, List<GatewayFlowRuleEntity>> gatewayFlowRuleEntityDecoder() {
        return new Converter<String, List<GatewayFlowRuleEntity>>() {
            @Override
            public List<GatewayFlowRuleEntity> convert(String source) {
                return JSON.parseArray(source, GatewayFlowRuleEntity.class);
            }
        };
    }

    @Bean
    @Primary
    public ConfigService nacosConfigService(NacosPropertiesConfiguration nacosPropertiesConfiguration) throws NacosException {
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, nacosPropertiesConfiguration.getServerAddr());
        properties.put(PropertyKeyConst.NAMESPACE, nacosPropertiesConfiguration.getNamespace());

        return ConfigFactory.createConfigService(properties);
    }
}
